package ecustom.common.util;

import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class DESUtil {
	
	private static final String DEFAULT_KEY = "des.util";
	private static final String DEFAULT_CHARSET_NAME = "UTF-8";
	private static final Map<String, Cipher> CIPHER_MAP = new HashMap<>();
	
	public static String encryptBase64(String str) {
		return encryptBase64(str, DEFAULT_KEY);
	}
	
	public static String encryptBase64(String str, String key) {
		try {
			byte[] data = encrypt(str.getBytes(DEFAULT_CHARSET_NAME), key);
			return Base64Util.encode(data);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	public static byte[] encrypt(byte[] data) {
		return encrypt(data, DEFAULT_KEY);
	}
	
	public static byte[] encrypt(byte[] data, String key) {
		try {
			return getCipher(key, Cipher.ENCRYPT_MODE).doFinal(data);
		} catch(Throwable e){
			e.printStackTrace();
		}
		return null;
	}
	
	public static String decryptBase64(String str) {
		return decryptBase64(str, DEFAULT_KEY);
	}
	
	public static String decryptBase64(String str, String key) {
		try {
			byte[] data = decrypt(Base64Util.decode(str), key);
			return new String(data, DEFAULT_CHARSET_NAME);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	public static byte[] decrypt(byte[] data) {
		return decrypt(data, DEFAULT_KEY);
	}
	
	public static byte[] decrypt(byte[] data, String key) {
		try {
			return getCipher(key, Cipher.DECRYPT_MODE).doFinal(data);
		} catch(Throwable e){
			e.printStackTrace();
		}
		return null;
	}
	
	public static Cipher getCipher(String key, int mode) {
		String mapKey = key + "|" + mode;
		try {
			key = getKey(key);
			if (!CIPHER_MAP.containsKey(mapKey)) {
				SecureRandom random = new SecureRandom();
				DESKeySpec desKey = new DESKeySpec(key.getBytes(DEFAULT_CHARSET_NAME));
				SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
				SecretKey securekey = keyFactory.generateSecret(desKey);
				Cipher cipher = Cipher.getInstance("DES");
				cipher.init(mode, securekey, random);
				CIPHER_MAP.put(mapKey, cipher);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return CIPHER_MAP.get(mapKey);
	}
	
	private static String getKey(String key) {
		if (key.length() < 8) {
			int bit = 8 - key.length();
			while (bit-- > 0) key += "=";
		}
		return key;
	}
}